#include "stdafx.h"

using namespace System;
using namespace System::Text;
using namespace System::Collections::Generic;
using namespace Microsoft::VisualStudio::TestTools::UnitTesting;

using namespace Gharen::GLCore;

namespace TestMath
{
	[TestClass]
	public ref class Vector4Tests
	{
	private:
		TestContext^ testContextInstance;

	public: 
		/// <summary>
		///Gets or sets the test context which provides
		///information about and functionality for the current test run.
		///</summary>
		property Microsoft::VisualStudio::TestTools::UnitTesting::TestContext^ TestContext
		{
			Microsoft::VisualStudio::TestTools::UnitTesting::TestContext^ get()
			{
				return testContextInstance;
			}
			System::Void set(Microsoft::VisualStudio::TestTools::UnitTesting::TestContext^ value)
			{
				testContextInstance = value;
			}
		};

		#pragma region Additional test attributes
		//
		//You can use the following additional attributes as you write your tests:
		//
		//Use ClassInitialize to run code before running the first test in the class
		//[ClassInitialize()]
		//static void MyClassInitialize(TestContext^ testContext) {};
		//
		//Use ClassCleanup to run code after all tests in a class have run
		//[ClassCleanup()]
		//static void MyClassCleanup() {};
		//
		//Use TestInitialize to run code before running each test
		//[TestInitialize()]
		//void MyTestInitialize() {};
		//
		//Use TestCleanup to run code after each test has run
		//[TestCleanup()]
		//void MyTestCleanup() {};
		//
		#pragma endregion 

		bool AreEqual(float left, float right)
		{
			if(Math::Abs(left-right) < Single::Epsilon)
				return true;
			return false;
		}

		bool AreEqual(Vector4 left, glm::vec4 right)
		{
			return AreEqual(left.X, right.x) &&
					AreEqual(left.Y, right.y) &&
					AreEqual(left.Z, right.z) &&
					AreEqual(left.W, right.w);
		}


		[TestMethod]
		void Vector4MultiplyMatrix()
		{
			Vector4 glCoreVector = Matrix::CreateLookAt(Vector3(10, 11, 12), Vector3(-30, 2, 3), Vector3(0,1,0))
				* Vector4(10, 40, 50, 23);

			glm::vec4 glmVector = glm::lookAt(glm::vec3(10, 11, 12), glm::vec3(-30, 2, 3), glm::vec3(0, 1, 0))
				* glm::vec4(10, 40, 50, 23);

			Assert::IsTrue(AreEqual(glCoreVector, glmVector));
		}

		[TestMethod]
		void Vector4DivideFloat()
		{
			Vector4 glCoreVector(12, -32, 42, 11);
			glCoreVector /= -23.1f;

			glm::vec4 glmVector(12, -32, 42, 11);
			glmVector /= -23.1f;

			Assert::IsTrue(AreEqual(glCoreVector, glmVector));
		}

		[TestMethod]
		void Vector4Dot()
		{
			float glCoreDot = Vector4::Dot(Vector4(100, 23, -32, 99), Vector4(342, 4, 2, -5));

			float glmDot = glm::dot(glm::vec4(100, 23, -32, 99), glm::vec4(342, 4, 2, -5));

			Assert::IsTrue(AreEqual(glCoreDot, glmDot));
		}

		[TestMethod]
		void Vector4MultiplyFloat()
		{
			Vector4 glCoreMatrix = Vector4(100, 23, -32, 99) * 0.5f;

			glm::vec4 glmMatrix = glm::vec4(100, 23, -32, 99) * 0.5f;
			
			Assert::IsTrue(AreEqual(glCoreMatrix, glmMatrix));
		}

		[TestMethod]
		void Vector4AddFloat()
		{
			Vector4 glCoreMatrix = Vector4(100, 23, -32, 99) + 10.5f;

			glm::vec4 glmMatrix = glm::vec4(100, 23, -32, 99) + 10.5f;
			
			Assert::IsTrue(AreEqual(glCoreMatrix, glmMatrix));
		}
	};
}